(function (root) {
  var Bmob = require('./bmob.js');
  const default_info= require('./als_config')// 1.h5 2.小程序 3.cocos 4.nodejs 5.头条游戏
  Bmob.initialize(default_info.bmob_key, default_info.bmob_secret);
  const is_debug=false;
  const firstName=default_info.firstName,lastName=default_info.lastName;
  const load_time = 900;

  var Als = {}
  const isObject = targe => Object.prototype.toString.call(targe) === '[object Object]'
  const isNumber = targe => Object.prototype.toString.call(targe) === '[object Number]'
  const isString = targe => Object.prototype.toString.call(targe) === '[object String]'
  const isUndefined = targe => Object.prototype.toString.call(targe) === '[object Undefined]'
  const isBoolean = targe => Object.prototype.toString.call(targe) === '[object Boolean]'
  const isArray = targe => Object.prototype.toString.call(targe) === '[object Array]'
  const isFunction = targe => Object.prototype.toString.call(targe) === '[object Function]'
  const err5 = "传入字段参数,类型不正确"
  const API = ''
  const Uniacid = 66, Uid = 1021;

  const getAppType = () => {
    let type
    // h5
    if (typeof wx !== 'undefined') {
      // 小程序
      type = 'wx'
    } else if (typeof cc !== "undefined") {
      //cocos
      type = 'cc'
    } else if (typeof qq !== "undefined") {
      //cocos
      type = 'cc'
    } else if (typeof window !== 'undefined') {
      type = 'h5'
    } else if (typeof tt !== "undefined") {
      //cocos
      type = 'tt'
    } else if (process === global.process) {
      // nodejs
      type = 'nodejs'
    } else {
      // 默认H5
      type = 'h5'
    }
    return type
  }
  var appSelf = () => {

    // return typeof wx ? wx: typeof tt ? tt
  }
  const getRandomArr = (arr, count) => {
    var shuffled = arr.slice(0), i = arr.length, min = i - count, temp, index;

    while (i-- > count) {
      index = Math.floor((i + 1) * Math.random());
      temp = shuffled[index]
      shuffled[index] = shuffled[i]
      shuffled[i] = temp;
    }
    return shuffled.slice(min);
  }
  const myRandomArr = (count) => {//成语
    var right = ['a', 'b', 'c']//正确字符串数组
    var str = right.split("")
    var arr = ['1', '2', '3', '5']//干扰字符串
    var shuffled = arr.slice(0), i = arr.length, min = i - count, temp, index;

    while (i-- > count) {
      index = Math.floor((i + 1) * Math.random());
      temp = shuffled[index]
      shuffled[index] = shuffled[i]
      shuffled[i] = temp;
    }
    var item = shuffled.slice(min);
    var newarr = Array.from(new Set(item));//去重
    var itemarr = newarr.concat(str)

    itemarr.sort(function () {
      return Math.random() > 0.5 ? -1 : 1;//乱序
    })
    return itemarr;
  }


  Als = {
    version: 1.1,
    url: "",
    Uid: Uid,
    Uniacid: Uniacid,
    type: getAppType(),
    localstorage:{},
    randNum(min, max) { //返回随机值
      var range = max - min;
      var rand = Math.random();
      var num = min + Math.round(rand * range)
      return num;
    },
    getAppType() { //返回平台类型
      return this.type;
    },
    getOpenid (code='') {
      var self=this
    
      return new Promise(function (resolve, reject) {
        var openid = self.localstorage.get('openid')
        if(openid){
          resolve(openid);
        }
        if (code) {
        if(typeof qq !== "undefined"||self.type=='qq'){
          console.error("qq==")
             let APPID=1110447486;
            let SECRET="uoe1vOTvzTUmpVUL";
              let url="https://api.q.qq.com/sns/jscode2session?appid="+APPID+"&secret="+SECRET+"&js_code="+code+"&grant_type=authorization_code";
    qq.request({
    url:url, 
      header: {
        'content-type': 'application/json' // 默认值
      },
      success(res) {
        let openid = res.data.openid
   
        wx.setStorageSync('openid',res.data.openid);
             resolve(openid);

      },
      fail(res){
          reject("请求异常，请重试！");
      },
    })
  }else{
    Bmob.User.requestOpenId(code).then((res) => {
      if (res && res.openid) {
        openid = res.openid
        resolve(openid);
        self.localstorage.set('openid', openid)
      }else{
        console.log(res)
        reject("请求异常，请重试！");
      }
    })
  }
           
          }
        
      })

    
    },
    getRandNum(e,t){
      var n = t - e, r = Math.random();
      return e + Math.round(r * n);
    },
    getRandName(){
      var self=this
      var t =firstName.length, n = lastName.length;
      return firstName[self.getRandNum(0, t - 1)] +lastName[self.getRandNum(0, n - 1)];
    },
    getRandColor(){
      let rgb = []
      for (let i = 0; i < 3; ++i) {
        let color = Math.floor(Math.random() * 256).toString(16)
        color = color.length == 1 ? '0' + color : color
        rgb.push(color)
      }
      return '#' + rgb.join('')
    },
    bmobFunc(tablename, method = '', param = '', attr = '', include = '') {
      var self = this;
      const query = Bmob.Query(tablename);
      const openid=self.localstorage.get('openid')
      var order_desc = "-updatedAt";
      var limit_num = 100;
      if (self.notEmpty(attr)) {
        if(attr.order!=""&&attr.order!=undefined){
           order_desc=attr.order    
          query.order(order_desc);
        }
        if(attr.select!=undefined){
          query.select(attr.select);
        }
        if (attr.limit != "" && attr.limit != undefined){
          limit_num=attr.limit
          if(attr.skip!=''&&attr.skip>0){
            query.skip(attr.skip*attr.limit)
          }
        }
       
      }
      if (self.notEmpty(include)) {
        query.include(include);
      }
    
      query.limit(limit_num);
   
      // query.skip(10);
      if (is_debug) {
        console.log(query)
      }
      var pro_fn = new Promise(function (resolve, reject) {
        switch (method) {
          case 'all':
            if (param.constructor === Object) {
              if(param.notlike!=undefined){
                if(param.like!=undefined){
                  query.equalTo(param.like.k, '==', param.like.v)
                }
                query.equalTo(param.notlike.k, '!=', param.notlike.v)
                if(param.notlike2!=undefined){
                  query.equalTo(param.notlike2.k, '!=', param.notlike2.v)
                }
                
              }else{
                for (let key in param) {
                  query.equalTo(key, '==', param[key])
                }
              }
          
            
            }
            console.log(attr.bigfield)
            console.log("attr=")
            if (attr.bigfield !=undefined){
              console.log('大于==')
           
              query.equalTo(attr.bigfield.k, '>=', attr.bigfield.v);
              // query.equalTo(attr.bigfield.k, ">", attr.bigfield.v);
            }
            if(attr.gtfield!=undefined){
              query.equalTo(attr.gtfield.k, '<=', attr.gtfield.v);
            }
            console.log(query)
            query.find().then(res => {
          
              if (is_debug) {
                console.log("我是全部")
                console.log(res)
              }
              resolve(res);
            });
            break;
          case 'update':
            if (param.constructor === Object) {
              for (let key in param) {
                query.set(key, param[key])
              }
            }
            query.save().then(res => {
              console.log(res)
              resolve(res);
            }).catch(err => {
              console.log(err)
            });
            break;
          case 'get_one':
            query.get(attr).then(res => {//查改
              console.log(res)
              if (param.constructor === Object) {
                for (let key in param) {
                  res.set(key, param[key])
                }
                res.save();
              }
              resolve(res);
            }).catch(err => {
              console.log(err)
            })
            break;
          case 'inc':
            if (param.constructor === Object&&param.id!=undefined) {
              var num=1;
              if (param.num != '' && param.num!=undefined){
                num = param.num
              }
              query.get(param.id).then(res => {
                res.increment(param.field,num)
                res.save()
                resolve(res);
              }).catch(err => {
                console.log(err)
              })
            }
          break;
          case 'add':
        
            if (param.constructor === Object) {//添加
              for (let key in param) {
                query.set(key, param[key])
              }
              query.save().then(res => {
                resolve(res);
              }).catch(err => {
                console.log(param)

                console.log(err)
              })
            }
            break;
          case 'del_one':
            query.destroy(attr).then(res => {
              console.log(res)
              resolve(res);
            }).catch(err => {
              console.log(err)
            })
            break;
          default:
            if (param.constructor === Object) {
              for (let key in param) {
                if(key=='openid'){
                  query.equalTo('openid', "==",openid);
                }else{
                  query.equalTo(key, "==", param[key]);
                }
               
              }
            }
            query.find().then(res => {
              if (self.notEmpty(res)) {
                if (is_debug) {
                  console.log(res[0])
                }
                resolve(res[0]);
              }else{
                reject('请求失败')
              }

            });
        }

      })
      return pro_fn;

    },
    getUser(uid=''){
      var self=this
      return new Promise(function (resolve, reject) {
     self.getOpenid().then(openid=>{
     
      const query =Bmob.Query('_User');
      query.equalTo('openid', '==', openid)


        query.find().then((res)=>{
        
          if(res){
            resolve(res[0]);
          }else{
            reject("请求异常，请重试！");
          }
        })
      })
 
     })
    
    },
    notEmpty(obj) {
      // 检验 undefined 和 null 参数检测
      if (!obj || obj == '' || obj == undefined) { return false; }
      if (Array.prototype.isPrototypeOf(obj) && obj.length === 0) { return false; }
      if (Object.prototype.isPrototypeOf(obj) && Object.keys(obj).length === 0) { return false; }
      return true;
    },
    setConfig(Uniacid = "", Uid = "") {
      this.Uniacid = Uniacid,
        this.Uid = Uid
    },
    funcWhere() {
      var errs = new Error().stack
      console.log(errs)
      var names = new Error().stack.match(/at (.*?) /g);
      var name = names[1].replace('at Object.', '').trim();
      return name;
    },



    sendPost(url, params = "", method = "post") {
      let xhr = new XMLHttpRequest();
      return new Promise(function (resolve, reject) {
        if (method == "post") {
          xhr.open('POST', url, true);
          xhr.setRequestHeader('Access-Control-Allow-Origin', '*');

          xhr.setRequestHeader("Content-Type", "application/json");
          xhr.setRequestHeader('X-Uniacid', Uniacid);
          xhr.setRequestHeader('X-Uid', Uid);

          xhr.send(JSON.stringify(params));
        } else {
          xhr.open("GET", url, true);
          xhr.send();
        }
        xhr.onreadystatechange = function () {
          if (xhr.readyState === 4 && xhr.status == 200) {
            let respone = xhr.responseText;
            let res = JSON.parse(respone);
            if (res.status == 1 || res.status == '1') {
              var data = res.data;
              console.log(res)
              resolve(res.data.data);
            } else {
              reject("请求异常，请重试！");
            }
          }
        };
      })
    },
  }
  var send = (url, params = "", method = "post") => {
    if (url.length < 16) {
      url = API + url
    }
    var xhr = new XMLHttpRequest();
    return new Promise(function (resolve, reject) {
      if (method == "post") {
        xhr.open('POST', url, true);
        xhr.setRequestHeader('Access-Control-Allow-Origin', '*');

        xhr.setRequestHeader("Content-Type", "application/json");
        xhr.setRequestHeader('X-Uniacid', Uniacid);
        xhr.setRequestHeader('X-Uid', Uid);
        xhr.send(JSON.stringify(params));
      } else {
        xhr.open("GET", url, true);
        xhr.send();
      }
      xhr.onreadystatechange = function () {
        if (xhr.readyState === 4 && xhr.status == 200) {
          var respone = xhr.responseText;
          var res = JSON.parse(respone);
          if (res.status == 1 || res.status == '1') {

            resolve(res.data);
          } else {
            if (res.status == 0) {
              throw new Error(JSON.stringify(res))
            }
            reject(res);
          }
        }
      };
    })

  }
  var wxsend = (url, params, method = "post") => {
    if (url.length < 16) {
      url = API + url
    }
    return new Promise(function (resolve, reject) {

      wx.request({
        url: url,
        method: method,
        data: params,
        // header:a,
        success: res => {
          if (res.data.status == 1) {
            resolve(res.data);
          } else {
            if (res.status == 0) {
              throw new Error(JSON.stringify(res))
            }
            reject(res);
          }
        },
        fail: e => {
          reject(e)
        }
      })
    })

  }
  var ttsend = (url, params, method = "post") => {
    if (url.length < 16) {
      url = API + url
    }
    return new Promise(function (resolve, reject) {

      tt.request({
        url: url,
        method: method,
        data: params,
        // header:a,
        success: res => {
          if (res.data.status == 1) {
            resolve(res.data);
          } else {
            if (res.status == 0) {
              throw new Error(JSON.stringify(res))
            }
            reject(res);
          }
        },
        fail: e => {
          reject(e)
        }
      })
    })

  }

  var appType = getAppType();
  var pre = Als.type + '_' + Als.version + '_'
  var localstorage = {
    set(name, value) {
      if (isObject(value)) {
        value = JSON.stringify(value)
      }
      return window.localStorage(pre + name, value)
    },
    get(name) {
      if (!isString(name)) throw new Error(err5);
      return JSON.parse(window.localStorage.getItem(pre + name)) || null
    },
    remove(name) {
      return window.localStorage.removeItem(pre + name)
    }
  }
  var wxlocalstorage = {
    set(name, value) {
      if (!isString(name) || !value) throw new Error(err5);
      return value = isObject(value) ? JSON.stringify(value) : value, wx.setStorageSync(pre + name, value)
    },
    get(name) {
      if (!isString(name)) throw new Error(err5);
      return wx.getStorageSync(pre + name) || null
    },
    remove(name) {
      if (!isString(name)) throw new Error(err5);
      return wx.removeStorageSync(pre + name)
    }
  }
  var ttlocalstorage = {
    set(name, value) {
      if (!isString(name) || !value) throw new Error(err5);
      return value = isObject(value) ? JSON.stringify(value) : value, tt.setStorageSync(pre + name, value)
    },
    get(name) {
      if (!isString(name)) throw new Error(err5);
      return tt.getStorageSync(pre + name) || null
    },
    remove(name) {
      if (!isString(name)) throw new Error(err5);
      return tt.removeStorageSync(pre + name)
    }
  }

  switch (appType) {
    case 'wx':
      send = wxsend;
      Als.localstorage = wxlocalstorage;
      wx.Als = Als;
      break;
    case 'tt':
      send = ttsend;
      Als.localstorage = ttlocalstorage;
      tt.Als = Als;
      break;
    case 'nodejs':
      context.Als = Als;
      break;

    default:
      Als.localstorage = localstorage;
      window.Als = Als
  }


  // var D = ['geta', 'getb']
  // for (var i = 0; i < D.length; i++) {
  //   !function (e) {
  //     Als[e] = function (data, method = 'post') {
  //       var name = funcWhere()
  //       console.log(name)
  //       send(name, data, method)
  //     }
  //   }(D[i])

  // }

  if (typeof exports !== "undefined") {
    if (typeof module !== "undefined" && module.exports) {
      exports = module.exports = Als
    }
    exports.Als = Als
  } else {
    root.Als = Als
  }

}.call(this));